import { store } from "@/store";
import { defineStore } from "pinia";
import { ref, watch, computed } from "vue";
import {
  SubjectTypeEnum,
  SubjectStatusEnum,
} from "@/enum/question-test/QuestionTestEnum";
import { SelectSubjectType, FormattedItem } from "./types";
import type { Swiper as SwiperType } from "swiper";
import { getLocalSubjectData } from "@/utils/question-test";
import { shuffle } from "@/utils";
import { ElMessage } from "element-plus";

export const useQuestionStore = defineStore("question", () => {
  /** 加载 */
  const loading = ref(true);
  /** 当前刷题模式：全部题型、单选题、多选题、判断题、三选题、二选题 */
  const curMode = ref<SubjectTypeEnum>(SubjectTypeEnum.ALL);
  /** 选择的题项 */
  const subjects = ref<SelectSubjectType[]>([]);
  /** 当前为第几题 */
  const curIndex = ref(0);
  /** 当前记录 */
  const record = ref<SelectSubjectType>();
  /** Swiper实例 */
  const swiperInstance = ref<SwiperType | undefined>();
  /**总条数 */
  const total = ref(0);

  /** 参考答案 */
  const referenceAnswer = computed(() => {
    return record.value?.correct.join("") ?? "null";
  });

  /** 当前题目是否选择完毕 */
  const isEnd = computed({
    get() {
      return record.value?.end ?? false;
    },
    set(val) {
      record.value!.end = val as boolean;
    },
  });

  watch(curMode, (newVal) => {
    if (newVal === curMode.value) {
      return;
    }
    // 模式更新，重新获取题目列表
    rest();
  });

  watch(curIndex, (newVal) => {
    // 下标更新，更新当前题目信息
    record.value = subjects.value[newVal];
    // console.log("当前题目索引更新，当前题目是否选择完毕==>", newVal, isEnd.value);
  });

  /**
   * 初始化文件数据
   */
  function initQuestion() {
    // 根据当前模式获取题目列表
    const list = shuffle(getLocalSubjectData(curMode.value)) as FormattedItem[];
    if (!list.length) {
      loading.value = false;
      return ElMessage.error("获取试题列表失败!");
    }
    subjects.value = loadData(list);
    // 记录总条数
    total.value = list.length;
    // 首次加载，保存第一题数据
    record.value = subjects.value[curIndex.value];
  }

  /**
   * 加载并格式化数据
   * @param list 题目列表
   * @param start 开始索引
   * @param end 结束索引
   */
  function loadData(
    list: FormattedItem[],
    start: number = 0,
    end: number = list.length
  ) {
    const result = [] as SelectSubjectType[];
    // 判断出入的start、end是否合法
    if (start < 0 || start >= end || end > list.length) {
      ElMessage.error("start、end参数错误");
      return result;
    }
    for (let i = start; i < end; i++) {
      const item = list[i];
      // 组装新选项
      const newItem = {
        // 它处于整个选择题的的索引
        index: i,
        // 题目
        topic: item.topic,
        // 题目类型
        type:
          item.select.length === 3
            ? SubjectTypeEnum.THREE_CHOICE
            : item.select.length === 2
            ? SubjectTypeEnum.TWO_CHOICE
            : item.subject,
        // 选项
        answers: item.answers,
        // 正确答案
        correct: item.select.split(""),
        // 是否正确选对该题
        status: SubjectStatusEnum.NOT_DONE,
        // 当前用户选中了哪个选项
        target: [],
        // 是否结束这一题
        end: false,
      } as SelectSubjectType;
      result.push(newItem);
    }
    return result;
  }

  /**
   * 多选题模式
   * @param item 题目信息
   * @param answer 用户选择的选项
   * @param index 题目索引
   */
  function multipleChoice(item: SelectSubjectType, answer: { title: string }) {
    if (isEnd.value) return;
    // console.log(`三选题，题目信息，第${index + 1}题==>`, item);
    // 用户选择的选项
    const targetItem = answer.title.charAt(0);
    // 当前题目用户选择的选项
    const selectTarget = record.value!.target;
    // 当前题目正确的选项
    const correctTarget = record.value!.correct;

    /* 判断题、单选题 */
    if (isJudgeOrSingle(item.type)) {
      selectTarget.push(targetItem);
      // 判断是否选择正确
      if (isCorrect(correctTarget, targetItem)) return onAllCorrect();
      // 错误，退出
      return onError();
    }
    // 第一次选择选项
    if (isFirstSelect(selectTarget)) {
      // 追加选项
      selectTarget.push(targetItem);
      // 第一次追加，并且选中的选项正确，直接退出
      if (isCorrect(correctTarget, targetItem)) return;
    }
    // 用户选择的选项不正确，直接显示错误答案
    if (!isCorrect(correctTarget, targetItem)) {
      // 追加本次错误选项
      !selectTarget.includes(targetItem) && selectTarget.push(targetItem);
      // console.log("用户选中错误选项==>", record.value, targetItem);
      return onError();
    }
    // 判断用户是否重复点击某个选项
    if (isRepeatClick(selectTarget, targetItem)) return;
    // 追加选项
    selectTarget.push(targetItem);

    // 是否全部正确选对
    if (isAllCorrect(selectTarget, correctTarget)) onAllCorrect();
  }

  /**
   * 当前试题用户选择完毕并且全部正确
   */
  function onAllCorrect() {
    console.log("用户全部正确选对");
    // 标记该题选择完毕
    isEnd.value = true;
    record.value!.status = SubjectStatusEnum.CORRECT;
    setTimeout(() => {
      // 如果用户手指滑动，就不自动跳转到下一题，animating：swiper是否正在过渡（自由滑动），true是，false否
      if (!swiperInstance.value?.animating) {
        // 自动跳转到下一题
        handleNext(swiperInstance.value);
      }
    }, 500);
  }

  /**
   * 当前试题用户选择错误
   */
  function onError() {
    // 标记该题选择完毕
    isEnd.value = true;
    record.value!.status = SubjectStatusEnum.ERROR;
  }

  /**
   * 是否为第一次选择
   * @param target 当前试题用户选择的选项字符串数组
   */
  function isFirstSelect(target: string[]) {
    return target.length === 0;
  }

  /**
   * 判断用户选择的选项是否正确
   * @param correct 当前题目正确的选项
   * @param select 用户选择的选项
   */
  function isCorrect(correct: string[], select: string) {
    return correct.includes(select);
  }

  /**
   * 判断用户是否重复点击某个选项
   * @param target 当前试题用户选择的选项字符串数组
   * @param select 用户选择的选项
   */
  function isRepeatClick(target: string[], select: string) {
    return target.findIndex((item) => item === select) >= 0;
  }

  /**
   * 判断用户是否选择了所有正确的选项
   * @param target 当前试题用户选择的选项字符串数组
   * @param correct 当前题目正确的选项字符串数组
   */
  function isAllCorrect(target: string[], correct: string[]) {
    return (
      target.every((item) => correct.includes(item)) &&
      target.length === correct.length
    );
  }

  /**
   * 判断当前模式是否为判断题或者单选题，由于判断题和单选题逻辑一样，所以将判断题的逻辑抽离出来
   */
  function isJudgeOrSingle(mode: SubjectTypeEnum) {
    return mode === SubjectTypeEnum.JUDGE || mode === SubjectTypeEnum.SINGLE;
  }

  /**
   * 上一题
   */
  function handlePrev(swiperInstance: SwiperType | undefined) {
    // if (swiperInstance?.isBeginning) {
    //   ElMessage.error("🐠已经是第一题了哦");
    //   return;
    // }
    swiperInstance?.slidePrev();
  }

  /**
   * 下一题
   */
  function handleNext(swiperInstance: SwiperType | undefined) {
    // if (swiperInstance?.isEnd) {
    //   ElMessage.error("🐟最后一题了哦");
    //   return;
    // }
    swiperInstance?.slideNext();
  }

  /**
   * 重置所有数据
   */
  function rest() {
    // 重置题目列表
    subjects.value = [];
    // 重置当前题目索引
    curIndex.value = 0;
    curMode.value = SubjectTypeEnum.ALL;
    // 重置当前题目记录
    record.value = undefined;
    // 重置Swiper实例
    swiperInstance.value = undefined;
  }

  return {
    total,
    loading,
    curMode,
    subjects,
    curIndex,
    record,
    swiperInstance,
    referenceAnswer,
    isEnd,
    rest,
    initQuestion,
    multipleChoice,
    handleNext,
    handlePrev,
  };
});

// 非setup
export function usePermissionStoreHook() {
  return useQuestionStore(store);
}
